package com.example.travel.controller;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundApplyResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.example.travel.common.AjaxResult;
import com.example.travel.common.Constants;
import com.example.travel.config.AliPayConfig;
import com.example.travel.domain.entity.AliPay;
import com.example.travel.domain.entity.Orders;
import com.example.travel.mapper.OrdersMapper;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author : LinQingLiang
 * @file : AllPayController.java
 * @Since : 2023/2/22 16:11
 */
//bwqmbm4103@sandbox.com

@RestController
@RequestMapping("alipay")
@Api(tags = "阿里支付")
public class AliPayController {

    private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    //签名方式
    private static final String SIGN_TYPE = "RSA2";


    @Resource
    private AliPayConfig aliPayConfig;

    @Autowired
    private OrdersMapper ordersMapper;

    @GetMapping("/pay")
    //1.创建client,通过sdk提供的client，负责调用支付宝的api
    public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        request.setBizContent("{\"out_trade_no\":\"" + aliPay.getTraceNo() + "\","
                + "\"total_amount\":\"" + aliPay.getTotalAmount() + "\","
                + "\"subject\":\"" + aliPay.getSubject() + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //2.执行请求，拿到相应的结果返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/notify")  // 注意这里必须是POST接口
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");

            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            // 支付宝验签
            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            Boolean checkSignature =  AlipaySignature.rsa256CheckContent(content,sign,aliPayConfig.getAlipayPublicKey(),"UTF-8");//验证签名
            if (checkSignature) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));

                // 更新订单未已支付
                ordersMapper.updateState(tradeNo, "已支付", gmtPayment, alipayTradeNo);
            }
        }
        return "success";
    }


    @GetMapping("return")
    public AjaxResult returnPay(AliPay aliPay) throws AlipayApiException{

        //七天无理由退款
        String now = DateUtil.now();
        Orders orders = ordersMapper.selectByTranceNo(aliPay.getTraceNo());
        if (orders != null) {
            //hutool工具类,判断时间间隔
            Long between = DateUtil.between(DateUtil.parseDateTime(orders.getPaymentTime()),DateUtil.parseDateTime(now), DateUnit.DAY);
            if (between > Constants.DAY_COUNT){
                return AjaxResult.error(-1,"该订单已经超过了七天不支持退款");
            }
        }

        //1.创建client,通过sdk提供的client，负责调用支付宝的api
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);

        //2.创建request并设置请求参数
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();

        JSONObject bizContent = new JSONObject();
        //支付宝回调的订单流水号
        bizContent.set("trade_no", aliPay.getAlipayTranceNo());
        //订单的总金额
        bizContent.set("refund_amount", aliPay.getTotalAmount());
        //我的订单编号
        bizContent.set("out_request_no", aliPay.getTraceNo());

        request.setBizContent(bizContent.toString());

        //3.执行请求
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()){
            System.out.println("调用成功");
            //4.更新数据库状态
            ordersMapper.updatePayState(aliPay.getTraceNo(),"已退款",now );
            return AjaxResult.success();
        }else{
            System.out.println(response.getBody());
            return AjaxResult.error(Integer.valueOf(response.getCode()),response.getBody());
        }
    }

}
